// Copyright (c) Microsoft Corporation. All rights reserved.


using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Xml.Serialization;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;

namespace Microsoft.TeamFoundation.Migration.Toolkit
{
    /*
     * 
     * <Tfs server="DevTFS">
     *   <Workspace>DemoTFS</Workspace>
     *   <WorkspaceRoot>c:\migration\workspace</WorkspaceRoot>
     * </Tfs>
     * 
     */

    /// <summary>
    /// The TFS version control end point.
    /// </summary>
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tfs")]
    [XmlType("Tfs")]
    public class TfsVersionControlTargetEndpoint : IVersionControlLinkableEndPoint
    {
        /// <summary>
        /// The TFS server to connect to.
        /// </summary>
        [XmlAttribute("server")]
        public string Server
        {
            get
            {
                return m_server;
            }
            set
            {
                m_server = value;
            }
        }

        /// <summary>
        /// The workspace to Create and use.
        /// </summary>
        public string Workspace
        {
            get
            {
                return m_workspace;
            }
            set
            {
                m_workspace = value;
            }
        }

        /// <summary>
        /// The root directory of the workspace.
        /// </summary>
        public string WorkspaceRoot
        {
            get
            {
                return m_workspaceRoot;
            }
            set
            {
                m_workspaceRoot = value;
            }
        }

        /// <summary>
        /// The VersionControl server service
        /// </summary>
        public VersionControlServer TfsClient
        {
            get
            {
                if (m_tfsClient == null)
                {            
                    TeamFoundationServer tfsServer = TeamFoundationServerFactory.GetServer(MigrationConfiguration.TfsServers[Server].Server);
                    m_tfsClient = (VersionControlServer)tfsServer.GetService(typeof(VersionControlServer));
                }
                return m_tfsClient;
            }
        }


        /// <summary>
        /// Given the artifact uri, returns the latest versioned item path on the Tfs server
        /// </summary>
        /// <param name="artifactUri">artifactUri to be queried</param>
        /// <returns>the server path of the item</returns>
        public string GetPathFromLatestItemVersion(string artifactUri)
        {
            try
            {
                Item item = TfsClient.ArtifactProvider.GetLatestItemVersion(new Uri(artifactUri));
                return item.ServerItem;
            }
            catch (VersionControlException e)
            {
                // It is possible that this is a deferred link. Then it is not an error.
                TraceManager.TraceInformation(e.Message);
                return null;
            }
        }

        /// <summary>
        /// Given the artifact uri, returns the versioned item path and changeset id on the Tfs server
        /// </summary>
        /// <param name="artifactUri">artifactUri to be queried</param>
        /// <param name="path">Out value, the server path of the versioned item</param>
        /// <param name="changeId">Out value, the changeset id of the versioned item</param>
        public void GetPathFromVersionedItem(string artifactUri, out string path, out string changeId)
        {
            try
            {
                Item item = TfsClient.ArtifactProvider.GetVersionedItem(new Uri(artifactUri));
                path = item.ServerItem;
                changeId = item.ChangesetId.ToString(CultureInfo.InvariantCulture);
                return;
            }
            catch (VersionControlException e)
            {
                // It is possible that this is a deferred link. Then it is not an error.
                TraceManager.TraceInformation(e.Message);
                path = null;
                changeId = null;
                return;
            }
        }

        /// <summary>
        /// Get latest item id from server path on the Tfs system
        /// </summary>
        /// <param name="path">the path of the item</param>
        public string GetLatestItemIdFromPath(string path)
        {
            try
            {
                Item item = TfsClient.GetItem(path, VersionSpec.Latest);
                return item.ItemId.ToString(CultureInfo.InvariantCulture);
            }
            catch (VersionControlException e)
            {
                // It is possible that this is a deferred link. Then it is not an error.
                TraceManager.TraceInformation(e.Message);
                return null;
            }
        }

        /// <summary>
        /// Get the revisioned item artifact uri from server path and changeid on the Tfs system
        /// </summary>
        /// <param name="path">the path of the item</param>
        /// <param name="changeId">changeId of the item</param>
        /// <returns>The artifact uri of the item found</returns>
        public string GetVersionedItemArtifactFromPathAndId(string path, string changeId)
        {
            try
            {
                Item item = TfsClient.GetItem(path);
                item = TfsClient.GetItem(item.ItemId, Convert.ToInt32(changeId, CultureInfo.InvariantCulture));
                return item.ArtifactUri.ToString();
            }
            catch (VersionControlException e)
            {
                // It is possible that this is a deferred link. Then it is not an error.
                TraceManager.TraceInformation(e.Message);
                return null;
            }
        }

        /// <summary>
        /// Given the original path, find the mapped path according to session mapping information
        /// </summary>
        /// <param name="path">The original path</param>
        /// <param name="session">The versioncontrolpath</param>
        /// <param name="useSource">True if the original path is source path.</param>
        /// <returns></returns>
        public string FindMappedPath(string path, VersionControlSession session, bool useSource)
        {
            return TfsUtil.FindMappedPath(path, session, useSource);
        }


        private string m_server;
        private string m_workspace;
        private string m_workspaceRoot;
        private VersionControlServer m_tfsClient;
    }
}
